WSL2 で md-to-pdf を使うために四苦八苦した話
いたくらです。
WSL2 で md-to-pdf を実行できるようになるまでをまとめました。
この記事で得られること
- WSL2(Linux ディストリビューション:Ubuntu)で md-to-pdf を実行するまでに必要な手順
実行環境
- エディション:Windows 11 Pro
- バージョン:22H2
- OS ビルド:22621.1702
Linux ディストリビューションについては以下コマンドで環境を確認します。
$ cat /etc/lsb-release DISTRIB_ID=Ubuntu DISTRIB_RELEASE=22.04 DISTRIB_CODENAME=jammy DISTRIB_DESCRIPTION="Ubuntu 22.04.2 LTS"
0. 大まかな手順
md-to-pdf は npm でインストールするので、前提として node を入れないといけないのですが、
「node を環境に直接ぶち込むのは良くない、Node.js のバージョン管理ツールを入れてやるべし」
とご指導いただき、さらに
「各言語にそれぞれ環境管理(env系)ツールがあるから anyenv でまとめて管理するといい」
とご教示いただいたので、以下の手順で進めます。
- anyenv インストール
- nodenv インストール
- node インストール
- md-to-pdf インストール
1. anyenv インストール
こちらを参考に進めました。
anyenv をダウンロード
git clone https://github.com/anyenv/anyenv ~/.anyenv
path を通す
下記のコードを
if [ -e "$HOME/.anyenv" ] then export ANYENV_ROOT="$HOME/.anyenv" export PATH="$ANYENV_ROOT/bin:$PATH" if command -v anyenv 1>/dev/null 2>&1 then eval "$(anyenv init -)" fi fi
./bashrc
に追記・保存しました。
./bashrc
に追記した設定を即座に反映させるために以下を実行します。
source ~/.bashrc
プラグインをインストール
nodenv をインストールするために、anyenv-install
のプラグインが必要。
自分は/home/ユーザ名/.anyenv/libexec/anyenv-install/
にインストールされました。
anyenv install --init
何env がインストールできるんだろう
nodenv 以外何があるんだろうと気になったので以下を実行します。
$ anyenv install --list Renv crenv denv erlenv exenv goenv hsenv jenv jlenv kubectlenv luaenv nodenv phpenv plenv pyenv rbenv sbtenv scalaenv swiftenv tfenv
めっちゃありました。ちゃんと nodenv もありました。
2. nodenv インストール
nodenv をインストール
以下を実行します。
anyenv install nodenv
インストールが完了すると以下が表示されます。
(省略) Install nodenv succeeded! Please reload your profile (exec $SHELL -l) or open a new session.
指示通りプロファイルのリロードを実行します。
exec $SHELL -l
以下を実行し、環境変数が追加されたか確認します。
$ env | grep nodenv NODENV_ROOT=/home/ユーザ名/.anyenv/envs/nodenv PATH=/home/ユーザ/.anyenv/envs/nodenv/shims:(以下省略)
ちゃんと追加されてるみたいなので OK です。
3. node インストール
Node.js のバージョン確認
インストール可能なバージョンを確認するために以下を実行します。
$ nodenv install -l
めっっっちゃ種類ある。
何がいいかわからないので以下を参照し、推奨版とされるv18.16.0
を導入します。
【参考】ダウンロード | Node.js
node をインストール
以下を実行します。
nodenv global
でコンピュータのデフォルトを指定しました。
$ nodenv install 18.16.0 $ nodenv global 18.16.0
nodenv local
を使って、特定ディレクトリ配下のバージョンを指定できるようなので、以下を実行します。
$ cd {開発作業をしているディレクトリ} $ nodenv local 18.16.0
こんな感じで特定ディレクトリ配下に.node-version
というファイルができます。
念のためバージョンを確認します。
$ node -v v18.16.0
npm 9.5.1 同梱だったので、そちらもバージョンを確認します。
$ npm -v 9.5.1
4. md-to-pdf インストール
こちらを参照し、以下を実行します。
【参考】simonhaenisch/md-to-pdf: Hackable CLI tool for converting Markdown files to PDF using Node.js and headless Chrome.
$ npm i -g md-to-pdf
実行後、以下が表示されました。
added 230 packages in 44s 15 packages are looking for funding run `npm fund` for details npm notice npm notice New minor version of npm available! 9.5.1 -> 9.7.1 npm notice Changelog: https://github.com/npm/cli/releases/tag/v9.7.1 npm notice Run npm install -g [email protected] to update! npm notice
とりあえず言われた通りバージョンアップします。
$ npm install -g [email protected]
実行後、以下が表示されました。
removed 3 packages, and changed 64 packages in 3s 27 packages are looking for funding run `npm fund` for details
特に問題なさそうなので、再度インストールを実行します。
$ npm i -g md-to-pdf changed 230 packages in 7s 15 packages are looking for funding run `npm fund` for details
成功したっぽいです。
npm でパッケージをインストールしたらrehash コマンド
を実行して、nodenv に認識されているすべての Node.js の実行可能ファイルをインストールする必要があるらしいです。
【参考】【解決方法】nodenvで入れたnpmのグローバルインストールでパスが通らない場合の対処について | とあるクリエイターのエンジニアブログ
ということで、以下を実行します。
$ nodenv rehash
パスが通っていることを確認しつつ、バージョンを確認します。
$ md-to-pdf -v 5.2.4
インストールは完了、後は .md ファイルが PDF に変換できることを確認するだけ、
のはずでした。。。
5. md-to-pdf で PDF 変換できない(;;)
md-to-pdf を使って PDF 変換できるか確認しようと(実際は違うけど)こんな感じのコマンドを実行します。
$ md-to-pdf test.md > test.pdf
そしたら以下が返ってきました。
Puppeteer old Headless deprecation warning: In the near feature `headless: true` will default to the new Headless mode for Chrome instead of the old Headless implementation. For more information, please see https://developer.chrome.com/articles/new-headless/. Consider opting in early by passing `headless: "new"` to `puppeteer.launch()` If you encounter any bugs, please report them to https://github.com/puppeteer/puppeteer/issues/new/choose. Error: Failed to launch the browser process! /home/ユーザ名/.cache/puppeteer/chrome/linux-113.0.5672.63/chrome-linux64/chrome: error while loading shared libraries: libnss3.so: cannot open shared object file: No such file or directory TROUBLESHOOTING: https://pptr.dev/troubleshooting at Interface.onClose (/home/ユーザ名/.anyenv/envs/nodenv/versions/18.16.0/lib/node_modules/md-to-pdf/node_modules/@puppeteer/browsers/lib/cjs/launch.js:259:24) at Interface.emit (node:events:525:35) at Interface.close (node:internal/readline/interface:533:10) at Socket.onend (node:internal/readline/interface:259:10) at Socket.emit (node:events:525:35) at endReadableNT (node:internal/streams/readable:1359:12) at process.processTicksAndRejections (node:internal/process/task_queues:82:21)
わぁ・・・^ω^
調査:1~6 行目の文章
こちらは一旦放置して大丈夫そうなので Warning だけど無視することにします。
理由はこちらの記事を参照ください。
調査:8~9 行目の文章
エラーメッセージで調査すると、下記の記事と状況が似ていました。
どうやら依存関係にあるライブラリが見つからないというエラーみたいです。
記事にあるldd コマンド
を使用して、以下を実行します。
$ ldd /home/ユーザ名/.cache/puppeteer/chrome/linux-113.0.5672.63/chrome-linux64/chrome | grep "not found"
ldd コマンド
の詳細はこちらを参照ください。
【参考】Linuxコマンド【 ldd 】共有ライブラリへの依存関係を表示 - Linux入門 - Webkaru
返ってきた結果がこちら。
$ ldd /home/ユーザ名/.cache/puppeteer/chrome/linux-113.0.5672.63/chrome-linux64/chrome | grep "not found" libnss3.so => not found libnssutil3.so => not found libsmime3.so => not found libnspr4.so => not found libatk-1.0.so.0 => not found libatk-bridge-2.0.so.0 => not found libcups.so.2 => not found libxkbcommon.so.0 => not found libatspi.so.0 => not found libXcomposite.so.1 => not found libXdamage.so.1 => not found libXfixes.so.3 => not found libXrandr.so.2 => not found libgbm.so.1 => not found libpango-1.0.so.0 => not found libcairo.so.2 => not found libasound.so.2 => not found
全然足りないじゃん!!!!
足りないパッケージ集めの旅
ひとまず不足しているファイルは判明しました。
でもどのパッケージをインストールすればいいんでしょう。
同じ疑問を持った方がいらっしゃいました。
こちらを参考に、まずは一番上にあるlibnss3.so
を検索します。
検索結果が表示され、必要なパッケージ名が判明しました!
検索結果を見ると CPU のアーキテクチャごとにパッケージ名が異なるようだったので、
amd64 だろうと思いつつ念のため以下を実行して確認します。
$ lscpu Architecture: x86_64 CPU op-mode(s): 32-bit, 64-bit (省略) Vendor ID: AuthenticAMD Model name: AMD Ryzen 5 Microsoft Surface (R) Edition
AMD の x86_64 ということが確認できたので、libnss3
をインストールします。
$ sudo apt install libnss3
パッケージによって途中で Yes/No があったり無かったりでしたが、とりあえず全部 Yes で進めます。
インストール完了後、不足パッケージが減っているか確認します。
$ ldd /home/ユーザ名/.cache/puppeteer/chrome/linux-113.0.5672.63/chrome-linux64/chrome | grep "not found" libatk-1.0.so.0 => not found libatk-bridge-2.0.so.0 => not found libcups.so.2 => not found libxkbcommon.so.0 => not found libatspi.so.0 => not found libXcomposite.so.1 => not found libXdamage.so.1 => not found libXfixes.so.3 => not found libXrandr.so.2 => not found libgbm.so.1 => not found libpango-1.0.so.0 => not found libcairo.so.2 => not found libasound.so.2 => not found
ちゃんと減っています!
ということで、残りもひたすらファイルを検索、パッケージ特定・インストールを繰り返します。
最後のパッケージをインストール後、再度 .md ファイルが PDF に変換できることを確認します。
$ md-to-pdf test.md > test.pdf Puppeteer old Headless deprecation warning: In the near feature `headless: true` will default to the new Headless mode for Chrome instead of the old Headless implementation. For more information, please see https://developer.chrome.com/articles/new-headless/. Consider opting in early by passing `headless: "new"` to `puppeteer.launch()` If you encounter any bugs, please report them to https://github.com/puppeteer/puppeteer/issues/new/choose. $
(Warning は無視するとして)エラーが消えたし、PDF ファイルもできました!
るんるんで PDF ファイルを開いたら、日本語が全部お豆腐(□)になっていました・・・
6. 日本語フォントを入れましょう
日本語フォントがないんだからそりゃお豆腐になりますね。
こちらを参考にさっさとインストールします。
【参考】日本語フォント IPAフォントのインストール - Ubuntuサーバー構築入門 - Ubuntuサーバーでゼロから環境構築
$ sudo apt install -y fonts-ipafont $ fc-cache -fv $ fc-list | grep -i ipa /usr/share/fonts/opentype/ipafont-mincho/ipam.ttf: IPAMincho,IPA明朝:style=Regular /usr/share/fonts/opentype/ipafont-gothic/ipagp.ttf: IPAPGothic,IPA Pゴシック:style=Regular /usr/share/fonts/opentype/ipafont-mincho/ipamp.ttf: IPAPMincho,IPA P明朝:style=Regular /usr/share/fonts/opentype/ipafont-gothic/ipag.ttf: IPAGothic,IPAゴシック:style=Regular /usr/share/fonts/truetype/fonts-japanese-mincho.ttf: IPAMincho,IPA明朝:style=Regular /usr/share/fonts/truetype/fonts-japanese-gothic.ttf: IPAGothic,IPAゴシック:style=Regular
ちゃんとインストールされました。
再度、.md ファイル ⇒ PDF 変換を実施して、PDF ファイルを確認します。
できました~!!
あとがき
開発環境の構築は奥が深い。 WSL2 と仲良くなれるように頑張らないとなぁと思いました。
アノテーション株式会社について
アノテーション株式会社は、クラスメソッド社のグループ企業として「オペレーション・エクセレンス」を担える企業を目指してチャレンジを続けています。
「らしく働く、らしく生きる」のスローガンを掲げ、様々な背景をもつ多様なメンバーが自由度の高い働き方を通してお客様へサービスを提供し続けてきました。
現在当社では一緒に会社を盛り上げていただけるメンバーを募集中です。少しでもご興味あれば、アノテーション株式会社WEBサイトをご覧ください。